package com.hs;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.google.gson.Gson;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: hs
 * @Description:
 * @Date: Create in 10:02 2020/3/7
 */
public class TestFanxing<T> {



    private String name;

    private T data;

    public List<String> testM(String a) {
        System.out.println("111");
        return new ArrayList<>();
    }

    public static Map<String, TestFanxing<String>> testMap() {
        Map<String, TestFanxing<String>> map = new HashMap<>();
        TestFanxing<String> testFanxing = new TestFanxing<>();
        testFanxing.setName("nnn");testFanxing.setData("sss");
        map.put("1111",testFanxing);
        return map;
    }
   public static void main(String[] args) throws Exception{
       //TypeReference a = new TypeReference();
       //testJson();
       testFastJson();
   }

    /**
     * 大功告成 动态返回序列化
     * @throws Exception
     */
    public static void testFastJson() throws Exception{
        String jsonString = JSON.toJSONString(testMap());
        TypeReference typeReference = new TypeReference<Map<String, TestFanxing<String>>>() {};
        System.out.println(jsonString);
        Map<String, TestFanxing<String>> result = (Map<String, TestFanxing<String>>)JSON.parseObject(jsonString, typeReference);

        for (Method method : TestFanxing.class.getMethods()) {
            if (method.getName().equals("testMap")) {
                //ParameterizedType type = (ParameterizedType)method.getGenericReturnType();
                Type type = method.getGenericReturnType();
                //List<Type> types = getTypes(type);
                Object o = JSON.parseObject(jsonString, type);
                Object o1 = new Gson().fromJson(jsonString, type);
                System.out.println(o);
                System.out.println(o1);
            }
        }
    }

    private static List<Type> getTypes(Type type) {
        List<Type> list = new ArrayList<>();
        if(type instanceof ParameterizedType){
            list.add(((ParameterizedType) type).getRawType());
            for (Type sub : ((ParameterizedType) type).getActualTypeArguments()) {
                list.addAll(getTypes(sub));
            }
        }else{
            list.add(type);
        }
        return list;
    }

    public static void testJson(){
        List<String> list = new ArrayList<>();
        list.add("1111");list.add("222");list.add("3332");
        String respons = JSONArray.toJSONString(list);
        try {
            Method method = TestFanxing.class.getMethod("testM", String.class);
            Type type = method.getGenericReturnType();
            ParameterizedType ptype= ((ParameterizedType) type);
            System.out.println(ptype.getRawType());
            System.out.println(ptype.getOwnerType());
            Type type1 = ptype.getActualTypeArguments()[0];
            System.out.println(type1.getTypeName());
            Class<?> aClass = TestFanxing.class.getClassLoader().loadClass(type1.getTypeName());
            List<?> types = JSON.parseArray(respons, aClass);
            //List<String> types = JSON.parseArray(respons, String.class);
            System.out.println(types);

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void main1(String[] args) {
        for (Method method : TestFanxing.class.getMethods()) {
            if (!method.getName().equals("testM")) {
                continue;
            }
            //回参获取泛型测试
            /*System.out.println(method.getReturnType());
            System.out.println(method.getGenericReturnType());
            Type type = method.getGenericReturnType();
            if(type instanceof ParameterizedType){
                for (Type type1 : ((ParameterizedType) type).getActualTypeArguments()) {
                    System.out.println(type1);
                }
                //System.out.println("ParameterizedType");
            }*/
            //入参获取泛型测试
            for (Type type : method.getGenericParameterTypes()) {
                System.out.println(type);
                if (type instanceof ParameterizedType) {
                    for (Type type1 : ((ParameterizedType) type).getActualTypeArguments()) {
                        System.out.println(type1);
                    }
                    //System.out.println("ParameterizedType");
                }
            }
        }
        //创建带有泛型的对象？
    }


   /* private static JavaType getMethodReturnJavaType(Method method) {
        Type type = method.getGenericReturnType();
        //判断是否带有泛型
        if (type instanceof ParameterizedType) {
            Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
            //获取泛型类型
            Class rowClass = (Class) ((ParameterizedType) type).getRawType();
            JavaType[] javaTypes = new JavaType[actualTypeArguments.length];
            for (int i = 0; i < actualTypeArguments.length; i++) {
                //泛型也可能带有泛型，递归获取
                javaTypes[i] = getJavaType(actualTypeArguments[i]);
            }
            return TypeFactory.defaultInstance().constructParametricType(rowClass, javaTypes);
        } else {
            //简单类型直接用该类构建
            Class cla = (Class) type;
            return TypeFactory.defaultInstance().constructParametricType(cla, new JavaType[0]);
        }
    }

    private static JavaType getJavaType(Type actualTypeArgument) {
        JavaType javaType = new SimpleType(actualTypeArgument.getClass());
    }*/


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

}
